import prisma from '../../api/prisma';
import { ClientInfo, SessionData } from '../../types/session';

/**
 * 会话仓库层 - 提供会话数据的存取操作
 */
export class SessionRepository {
  /**
   * 创建或获取会话
   * 如果sessionId有效，则返回现有会话
   * 如果sessionId无效或不存在，则创建新会话
   * 如果sessionId存在但已过期，则使用该ID创建新会话
   */
  static async getOrCreate(
    sessionId?: string,
    isVip: boolean = false
  ): Promise<SessionData> {
    // 如果有会话ID，尝试获取现有会话
    if (sessionId) {
      const existingSession = await this.getById(sessionId);
      if (existingSession && existingSession.expiresAt > new Date()) {
        return existingSession;
      }
    }

    // 创建新会话
    const expiresAt = new Date();
    expiresAt.setDate(expiresAt.getDate() + 30); // 30天后过期

    return prisma.session.create({
      data: {
        ...(sessionId ? { id: sessionId } : {}),
        isVip,
        expiresAt,
        visitCount: 0
      }
    });
  }

  /**
   * 根据ID获取会话
   */
  static async getById(id: string): Promise<SessionData | null> {
    return prisma.session.findUnique({
      where: { id }
    });
  }

  /**
   * 更新会话
   */
  static async update(id: string, data: Record<string, any>): Promise<SessionData> {
    return prisma.session.update({
      where: { id },
      data
    });
  }

  /**
   * 设置VIP状态
   */
  static async setVipStatus(id: string, isVip: boolean): Promise<SessionData> {
    return this.update(id, {
      isVip,
      lastActivityAt: new Date()
    });
  }

  /**
   * 记录访问
   */
  static async recordVisit(id: string, path?: string, clientInfo?: ClientInfo): Promise<SessionData> {
    return this.update(id, {
      visitCount: {
        increment: 1
      },
      lastActivityAt: new Date(),
      lastVisitPath: path,
      ...(clientInfo ? {
        ipAddress: clientInfo.ipAddress,
        userAgent: clientInfo.userAgent,
        referrer: clientInfo.referrer,
        deviceType: clientInfo.deviceType
      } : {})
    });
  }

  /**
   * 清理过期会话
   */
  static async cleanupExpired(): Promise<number> {
    const result = await prisma.session.deleteMany({
      where: {
        expiresAt: {
          lt: new Date()
        }
      }
    });
    
    return result.count;
  }
} 